/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibust - IBus with Traditional interface
 *
 * Copyright (c) 2013 Daniel Sun
 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
 * Copyright (C) 2008-2010 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#if !defined (__IBUST_H_INSIDE__) && !defined (IBUST_COMPILATION)
#error "Only <ibust.h> can be included directly"
#endif

/**
 * SECTION: ibustcomponent
 * @short_description:  Component (executable) specification.
 * @title: IBustComponent
 * @stability: Stable
 *
 * An IBustComponent is an executable program.
 * It provides services such as user interface, configuration,
 * and input method engine (IME).
 *
 * It is recommended that IME developers provide
 * a component XML file and
 * load the XML file by ibust_component_new_from_file().
 *
 * The format of a component XML file is described  at
 * <ulink url="http://code.google.com/p/ibust/wiki/DevXML">http://code.google.com/p/ibust/wiki/DevXML</ulink>
 */
#ifndef __IBUST_COMPONENT_H_
#define __IBUST_COMPONENT_H_

#include "ibustserializable.h"
#include "ibustobservedpath.h"
#include "ibustenginedesc.h"
#include "ibustxml.h"

/*
 * Type macros.
 */

/* define GOBJECT macros */
#define IBUST_TYPE_COMPONENT             \
    (ibust_component_get_type ())
#define IBUST_COMPONENT(obj)             \
    (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUST_TYPE_COMPONENT, IBustComponent))
#define IBUST_COMPONENT_CLASS(klass)     \
    (G_TYPE_CHECK_CLASS_CAST ((klass), IBUST_TYPE_COMPONENT, IBustComponentClass))
#define IBUST_IS_COMPONENT(obj)          \
    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUST_TYPE_COMPONENT))
#define IBUST_IS_COMPONENT_CLASS(klass)  \
    (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUST_TYPE_COMPONENT))
#define IBUST_COMPONENT_GET_CLASS(obj)   \
    (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUST_TYPE_COMPONENT, IBustComponentClass))

G_BEGIN_DECLS

typedef struct _IBustComponent IBustComponent;
typedef struct _IBustComponentClass IBustComponentClass;
typedef struct _IBustComponentPrivate IBustComponentPrivate;

/**
 * IBustComponent:
 *
 * An IBustComponent stores component information.
 * You can get extended values with g_object_get_properties.
 * name: Name of the component.
 * description: Detailed description of component.
 * version: Component version.
 * license: Distribution license of this component.
 * author: Author(s) of the component.
 * homepage: Homepage of the component.
 * command_line: path to component executable.
 * textdomain: Domain name for dgettext()
 */
struct _IBustComponent {
    /*< private >*/
    IBustSerializable parent;
    IBustComponentPrivate *priv;
    /* instance members */

    /*< public >*/

    /* padding */
    gpointer pdummy[7];  // We can add 7 pointers without breaking the ABI.
};

struct _IBustComponentClass {
  IBustSerializableClass parent;

  /* class members */
};

GType            ibust_component_get_type        (void);

/**
 * ibust_component_new:
 * @name: Name of the component.
 * @description: Detailed description of component.
 * @version: Component version.
 * @license: Distribution license of this component.
 * @author: Author(s) of the component.
 * @homepage: Homepage of the component.
 * @command_line: path to component executable.
 * @textdomain: Domain name for dgettext()
 * @returns: A newly allocated IBustComponent.
 *
 * New an IBustComponent.
 */
IBustComponent   *ibust_component_new             (const gchar    *name,
                                                 const gchar    *description,
                                                 const gchar    *version,
                                                 const gchar    *license,
                                                 const gchar    *author,
                                                 const gchar    *homepage,
                                                 const gchar    *command_line,
                                                 const gchar    *textdomain);

/**
 * ibust_component_new_varargs:
 * @first_property_name: Name of the first property.
 * @Varargs: the NULL-terminated arguments of the properties and values.
 *
 * New an IBustComponent.
 * ibust_component_new_varargs() supports the va_list format.
 * name property is required. e.g.
 * IBustComponent *component = ibust_component_new_varargs ("name", "ibust-foo",
 *                                                        "command_line", "/usr/libexec/ibust-engine-foo --ibust",
 *                                                     NULL)
 */
IBustComponent   *ibust_component_new_varargs     (const gchar    *first_property_name,
                                                 ...);

/**
 * ibust_component_new_from_xml_node:
 * @node: Root node of component XML tree.
 * @returns: A newly allocated IBustComponent.
 *
 * New an IBustComponent from an XML tree.
 */
IBustComponent   *ibust_component_new_from_xml_node
                                                (XMLNode        *node);

/**
 * ibust_component_new_from_file:
 * @filename: An XML file that contains component information.
 * @returns: A newly allocated IBustComponent.
 *
 * New an IBustComponent from an XML file.
 * Note that a component file usually contains engine descriptions,
 * if it does, ibust_engine_desc_new_from_xml_node() will be called
 * to load the engine descriptions.
 */
IBustComponent   *ibust_component_new_from_file   (const gchar    *filename);

/**
 * ibust_component_get_name:
 * @component: An IBustComponent
 * @returns: name property in IBustComponent
 *
 * Return the name property in IBustComponent. It should not be freed.
 */
const gchar     *ibust_component_get_name        (IBustComponent  *component);

/**
 * ibust_component_get_description:
 * @component: An IBustComponent
 * @returns: description property in IBustComponent
 *
 * Return the description property in IBustComponent. It should not be freed.
 */
const gchar     *ibust_component_get_description (IBustComponent  *component);

/**
 * ibust_component_get_version:
 * @component: An IBustComponent
 * @returns: version property in IBustComponent
 *
 * Return the version property in IBustComponent. It should not be freed.
 */
const gchar     *ibust_component_get_version     (IBustComponent  *component);

/**
 * ibust_component_get_license:
 * @component: An IBustComponent
 * @returns: license property in IBustComponent
 *
 * Return the license property in IBustComponent. It should not be freed.
 */
const gchar     *ibust_component_get_license     (IBustComponent  *component);

/**
 * ibust_component_get_author:
 * @component: An IBustComponent
 * @returns: author property in IBustComponent
 *
 * Return the author property in IBustComponent. It should not be freed.
 */
const gchar     *ibust_component_get_author      (IBustComponent  *component);

/**
 * ibust_component_get_homepage:
 * @component: An IBustComponent
 * @returns: homepage property in IBustComponent
 *
 * Return the homepage property in IBustComponent. It should not be freed.
 */
const gchar     *ibust_component_get_homepage    (IBustComponent  *component);

/**
 * ibust_component_get_exec:
 * @component: An IBustComponent
 * @returns: exec property in IBustComponent
 *
 * Return the exec property in IBustComponent. It should not be freed.
 */
const gchar     *ibust_component_get_exec        (IBustComponent  *component);

/**
 * ibust_component_get_textdomain:
 * @component: An IBustComponent
 * @returns: textdomain property in IBustComponent
 *
 * Return the textdomain property in IBustComponent. It should not be freed.
 */
const gchar     *ibust_component_get_textdomain  (IBustComponent  *component);

/**
 * ibust_component_add_observed_path:
 * @component: An IBustComponent
 * @path: Observed path to be added.
 * @access_fs: TRUE for filling the file status; FALSE otherwise.
 *
 * Add an observed path to IBustComponent.
 */
void             ibust_component_add_observed_path
                                                (IBustComponent  *component,
                                                 const gchar    *path,
                                                 gboolean        access_fs);

/**
 * ibust_component_add_engine:
 * @component: An IBustComponent
 * @engine: A description of an engine.
 *
 * Add an engine to IBustComponent according to the description in @engine.
 */
void             ibust_component_add_engine      (IBustComponent  *component,
                                                 IBustEngineDesc *engine);

/**
 * ibust_component_get_engines:
 * @component: An IBustComponent.
 * @returns: (transfer container) (element-type IBustEngineDesc): A newly allocated GList that contains engines.
 *
 * Get the engines of this component.
 */
GList           *ibust_component_get_engines     (IBustComponent  *component);

/**
 * ibust_component_output:
 * @component: An IBustComponent.
 * @output: GString that holds the result.
 * @indent: level of indent.
 *
 * Output IBustComponent as an XML-formatted string.
 * The output string can be then shown on the screen or written to file.
 */
void             ibust_component_output          (IBustComponent  *component,
                                                 GString        *output,
                                                 gint            indent);

/**
 * ibust_component_output_engines:
 * @component: An IBustComponent.
 * @output: GString that holds the result.
 * @indent: level of indent.
 *
 * Output engine description  as an XML-formatted string.
 * The output string can be then shown on the screen or written to file.
 */
void             ibust_component_output_engines  (IBustComponent  *component,
                                                 GString        *output,
                                                 gint            indent);

/**
 * ibust_component_check_modification:
 * @component: An IBustComponent.
 * @returns: TRUE if at least one of the observed paths is modified; FALSE otherwise.
 *
 * Check whether the observed paths of component is modified.
 */
gboolean         ibust_component_check_modification
                                                (IBustComponent  *component);

/**
 * ibust_component_get_observed_paths:
 * @component: An IBustComponent.
 * @returns: (transfer container) (element-type IBustObservedPath): A
 * newly allocated GList that contains observed paths.
 *
 * Get the observed paths of this component.
 */
GList           *ibust_component_get_observed_paths
                                                (IBustComponent *component);

G_END_DECLS
#endif

